package com.admin.utils.base;

import java.util.*;
import java.util.concurrent.TimeUnit;

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.data.redis.core.HashOperations;
import org.springframework.data.redis.core.ListOperations;

import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SetOperations;
import org.springframework.data.redis.core.ValueOperations;
import org.springframework.data.redis.core.ZSetOperations;
import org.springframework.stereotype.Service;



/**
 *
 * ClassName:RedisServiceIm <br/>
 * Reason: TODO ADD REASON. <br/>
 * Date: 2019年9月3日 上午11:41:42 <br/>
 * 
 * @author Owner
 * @version
 * @since JDK 1.8
 * @see
 */
@Service
public class RedisManager  {

	public static final String LOCK_PREFIX = "redis_lock";

	public static final int LOCK_EXPIRE = 3000; // ms

	private Long expireExtendTime = 0L;

	public RedisManager(Long t) {
		this.expireExtendTime = (long) Math.random() * t;
	}

	public RedisManager() {
	}

	@Autowired
	private RedisTemplate<Object, Object> redisTemplate;

	public boolean set(String key, Object value) {
		try {
			ValueOperations<Object, Object> operations = redisTemplate.opsForValue();
			operations.set(key, value);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	public boolean set(String key, Object value, Long expireTime) {

		try {
			ValueOperations<Object, Object> operations = redisTemplate.opsForValue();
			operations.set(key, value);
			redisTemplate.expire(key, expireTime + expireExtendTime, TimeUnit.SECONDS);
			return true;
		} catch (Exception e) {
			return false;
		}
	}

	public void remove(String... keys) {
		for (String key : keys) {
			remove(key);
		}

	}

	public void removePattern(String pattern) {
		Set<Object> keys = redisTemplate.keys(pattern);
		if (keys.size() > 0) {
			redisTemplate.delete(keys);
		}
	}

	public void remove(String key) {
		if (exists(key)) {
			redisTemplate.delete(key);
		}
	}

	public boolean exists(String key) {
		return redisTemplate.hasKey(key);
	}

	@SuppressWarnings("unchecked")
	public <T> T get(String key) {

		ValueOperations<Object, T> operations = (ValueOperations<Object, T>) redisTemplate.opsForValue();
		return operations.get(key);
	}

	public void hmSet(String key, Object hashKey, Object value) {
		HashOperations<Object, Object, Object> hash = redisTemplate.opsForHash();
		hash.put(key, hashKey, value);
	}

	public void hmSet(String key, Object hashKey, Object value, Long expireTime) {

		HashOperations<Object, Object, Object> hash = redisTemplate.opsForHash();
		hash.put(key, hashKey, value);
		redisTemplate.expire(hashKey, expireTime + expireExtendTime, TimeUnit.SECONDS);

	}

	public Object hmGet(String key, Object hashKey) {
		HashOperations<Object, Object, Object> hash = redisTemplate.opsForHash();
		return hash.get(key, hashKey);
	}

	public void lPush(String k, Object v) {
		ListOperations<Object, Object> list = redisTemplate.opsForList();
		list.rightPush(k, v);
	}

	public List<Object> lRange(String key, long start, long stop) {
		ListOperations<Object, Object> list = redisTemplate.opsForList();
		return list.range(key, start, stop);
	}

	public void add(String key, Object value) {
		SetOperations<Object, Object> set = redisTemplate.opsForSet();
		set.add(key, value);
	}

	public Set<Object> setMembers(String key) {
		SetOperations<Object, Object> set = redisTemplate.opsForSet();
		return set.members(key);
	}

	public void zAdd(String key, Object value, double scoure) {
		ZSetOperations<Object, Object> zset = redisTemplate.opsForZSet();
		zset.add(key, value, scoure);
	}

	public Set<Object> rangeByScore(String key, double scoure, double scoure1) {
		ZSetOperations<Object, Object> zset = redisTemplate.opsForZSet();
		return zset.rangeByScore(key, scoure, scoure1);
	}

	public Map<Object, Object> hmMap(String key) {
		HashOperations<Object, Object, Object> operations = redisTemplate.opsForHash();
		Map<Object, Object> mapInRedis = operations.entries(key);
		return mapInRedis;
	}

	public Long incr(String key, long liveTime, Integer defaultValue) {
		Long ins = redisTemplate.opsForValue().increment(key, defaultValue == null ? 1L : defaultValue);
		redisTemplate.expire(key, liveTime, TimeUnit.SECONDS);
		return ins;
	}

	public Long getExpireTime(String key) {
		return redisTemplate.getExpire(key, TimeUnit.SECONDS);

	}

	@SuppressWarnings("unchecked")
	public <T> List<T> parmGet(String key) {
		List<T> res = new ArrayList<T>();

		Set<Object> keys = redisTemplate.keys(key + "*");
		for (Object s : keys) {
			res.add((T) get((String) s));
		}
		return res;
	}

	@SuppressWarnings("unchecked")
	public <T> Map<Long, T> getLiveTimeAndValue(String key) {

		Map<Long, T> res = new HashMap<Long, T>();
		res.put(redisTemplate.getExpire(key), (T) get(key));
		return res;
	}

	public void delyLiveTime(String key, Long secs) {

		redisTemplate.expire(key, secs, TimeUnit.SECONDS);

	}

}
